package elf

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"strings"
)

type F struct {
	dir string
	ex  string
	exf *os.File
}

func (t *F) setDir(d string) {
	t.dir = d
}

func (t *F) setEx(ex string) {
	t.ex = ex
}

func (t *F) initExf() {
	var err error
	t.exf, err = os.Open(t.ex)
	if err != nil {
		fmt.Println("没有文件 ", t.ex)
		os.Exit(1)
	}
}

func (t *F) Over() {
	i.exf.Close()
}

func (t *F) readFile(filename string) string {
	var fname = path.Join(t.dir, filename)
	f, err := os.Open(fname)
	if err != nil {
		return ""
	}

	r, err := ioutil.ReadAll(f)
	if err != nil {
		return ""
	}
	return string(r)

}

var i = &F{}

func Read(filename string) string {
	return i.readFile(filename)
}

func Init(dir string, ex string) {
	i.setDir(dir)
	i.setEx(ex)
	i.initExf()
}

func itemsCall(items []Item, data []byte) {
	var index = 0
	fmt.Println("body ##", data)
	for ii, item := range items {

		var size = item.Len
		var end int
		var body []byte
		if size > 0 {
			end = index + size
			body = data[index:end]
		} else {
			body = data[index:]
		}
		fmt.Println("##@@", index, end)

		if item.Def != nil {
			if string(body) != string(item.Def) {
				item.Err = errors.New("默认值错误")
			}
		}

		if len(item.Items) > 0 {
			itemsCall(item.Items, body[0:])
		}
		items[ii].Body = string(body)
		index = index + size

	}
}

func dingwei(filename string, index int) (string, int) {
	fArr := strings.Split(filename, "@")
	if len(fArr) > 1 {
		var f = fArr[0]
		var item = makeItem(f)
		return dingwei(strings.Join(fArr[1:], "@"), index+item.Len)

	} else {
		return fArr[0], index
	}

}

func makeItem(filename string) *Item {
	sbody := Read(filename)
	var rr Item
	err := json.Unmarshal([]byte(sbody), &rr)
	if err != nil {
		return nil
	}
	return &rr
}

func Run(filename string) string {

	var ff, index = dingwei(filename, 0)

	var rr = makeItem(ff)

	if rr == nil {
		return ""
	}

	var rArr []byte = make([]byte, rr.Len)

	n, err := i.exf.ReadAt(rArr, int64(index))
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	itemsCall(rr.Items, rArr[0:])
	fmt.Println(n)

	rbytes, err := json.Marshal(rr)
	if err != nil {
		return ""
	}
	return string(rbytes)

}
